package top.laoshuzi.cloudplatform.servo;

import com.google.android.things.contrib.driver.pwmservo.Servo;

import java.io.IOException;

/**
 * Created by mouse on 2017/12/20.
 */

public class ServoHandler implements AutoCloseable {

    public static final double MIN_ANGLE = 0;
    public static final double MAX_ANGLE = 270;
    public static final double MIN_DURATION = 0.7;
    public static final double MAX_DURATION = 2.6;

    private Servo horizontalServo;
    private Servo verticalServo;

    private ServoHandler() {
    }

    public static ServoHandler getInstance() {
        return InstanceHolder.INSTANCE;
    }

    private static class InstanceHolder {
        private static final ServoHandler INSTANCE = new ServoHandler();
    }

    @Override
    public void close() throws Exception {
        if (horizontalServo != null) {
            horizontalServo.close();
        }
        if (verticalServo != null) {
            verticalServo.close();
        }
    }

    public void initialize(double durationOffset0, double durationOffset1) throws IOException {
        horizontalServo = new Servo("PWM0");
        horizontalServo.setAngleRange(MIN_ANGLE, MAX_ANGLE);
        horizontalServo.setPulseDurationRange(MIN_DURATION + durationOffset0, MAX_DURATION + durationOffset0);
        horizontalServo.setEnabled(true);
        verticalServo = new Servo("PWM1");
        verticalServo.setAngleRange(MIN_ANGLE, MAX_ANGLE);
        verticalServo.setPulseDurationRange(MIN_DURATION + durationOffset1, MAX_DURATION + durationOffset1);
        verticalServo.setEnabled(true);
    }

    public void setHorizontalServoAngle(double angle) throws IOException, IllegalArgumentException {
        if (angle < MIN_ANGLE || angle > MAX_ANGLE) {
            throw new IllegalArgumentException("无效角度范围");
        }
        setServoAngle(horizontalServo, angle);
    }

    public void setVerticalServoAngle(double angle) throws IOException, IllegalArgumentException {
        if (angle < MIN_ANGLE || angle > MAX_ANGLE) {
            throw new IllegalArgumentException("无效角度范围");
        }
        setServoAngle(verticalServo, angle);
    }

    public void increaseHorizontalServoAngle(double angle) throws IOException, IllegalArgumentException {
        double ServoAngle = getHorizontalServoAngle() + angle;
        if (ServoAngle > MAX_ANGLE)
            ServoAngle = MAX_ANGLE;
        setServoAngle(horizontalServo, ServoAngle);
    }

    public void increaseVerticalServoAngle(double angle) throws IOException, IllegalArgumentException {
        double ServoAngle = getVerticalServoAngle() + angle;
        if (ServoAngle > MAX_ANGLE)
            ServoAngle = MAX_ANGLE;
        setServoAngle(verticalServo, ServoAngle);
    }

    public void decreaseHorizontalServoAngle(double angle) throws IOException, IllegalArgumentException {
        double ServoAngle = getHorizontalServoAngle() - angle;
        if (ServoAngle < MIN_ANGLE)
            ServoAngle = MIN_ANGLE;
        setServoAngle(horizontalServo, ServoAngle);
    }

    public void decreaseVerticalServoAngle(double angle) throws IOException, IllegalArgumentException {
        double ServoAngle = getVerticalServoAngle() - angle;
        if (ServoAngle < MIN_ANGLE)
            ServoAngle = MIN_ANGLE;
        setServoAngle(verticalServo, ServoAngle);
    }

    public double getHorizontalServoAngle() {
        return horizontalServo.getAngle();
    }

    public double getVerticalServoAngle() {
        return verticalServo.getAngle();
    }


    private void setServoAngle(Servo servo, double angle) throws IOException {
        servo.setAngle(angle);
    }

}
